import os, sys, pygame, math
from pygame.locals import *
import sqlite3 as sqlite

pygame.init()

c = pygame.time.Clock()
screen_width = 640 # this paragraph is just your standard pygame stuff
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("RPG")
camera_x, camera_y = screen_width/2, screen_height/2
camera_snap_to_hero = True

tile_size = 20

tileset = dict([(f.split('.')[0], pygame.image.load('tiles/'+f)) for f in os.listdir('tiles') if 'png' in f])
object_types = ["house"]
object_list = []

class object_base:
    # It has basic stuff that is needed by needy objects (like houses)
    def __init__(self, x, y, tiletype):
        self.x, self.y = x, y
        self.image = tileset[tiletype]
        self.image.set_colorkey((255,0,255))
        self.rect = self.image.get_rect()
        self.name = tiletype

    def draw(self):
        self.rect = self.image.get_rect().move((self.x*tile_size + camera_x, self.y*tile_size + camera_y))
        screen.blit(self.image, self.rect)

class Character:
    def __init__(self, x, y):
        self.x, self.y = x, y
        self.speed = 5
        # self.dir = "down" # short for "direction"
        # self.sprites = {}
        self.sprite = pygame.image.load("player.png")
        self.cur_sprite = pygame.image.load("player.png")
        self.cur_sprite.set_colorkey((255,255,255))
        self.rect = self.cur_sprite.get_rect()
    def update(self, pressed_keys):
        self.cur_sprite = pygame.transform.rotate(self.sprite, math.atan2(mouseY - self.y-camera_y, mouseX - self.x-camera_x)*180/math.pi*-1)
        self.cur_sprite.set_colorkey((255,255,255))
        self.draw()
        self.movement()
    def draw(self):
        screen.blit(self.cur_sprite, (self.x + camera_x, self.y + camera_y))
    def movement(self):
        x, y = 0, 0
        if pressed_keys[K_a]:
            x = -self.speed
        if pressed_keys[K_d]:
            x = self.speed
        if pressed_keys[K_s]:
            y = self.speed
        if pressed_keys[K_w]:
            y = -self.speed
        self.rect = pygame.Rect((screen_width/2)+x, (screen_height/2)+y, self.sprite.get_width(), self.sprite.get_height())
        move = True
        #for xx in range(-1, 2):
            #for yy in range(-1, 2):
                #if tilelist[(self.x/20)+xx, (self.y/20)+yy] == "water" and Rect( (((self.x/20)+xx)*20)+camera_x, (((self.y/20)+yy)*20)+camera_y, 20, 20).colliderect((self.x)+camera_x, (self.y)+camera_y, 15, 15):
                    #move = False
                    #break
        future_x, future_y = self.x+x, self.y+y
        future_square = ((future_x/20)*20, (future_y/20)*20)
        if Rect(future_x, future_y, 15, 15).colliderect( (future_x/20)*20, (future_y/20)*20, 20, 20) and tilelist[(future_x/20, future_y/20)] == "water":
            move = False
        if move == True:
            self.x += x
            self.y += y
            
Hero = Character(10, 10)
badguy = Character(50, 50)

class Bullet:
    def __init__(self):
        self.x, self.y = Hero.x, Hero.y
        self.speed = 30
        self.angle = math.atan2(mouseY - (self.y+camera_y), mouseX - (self.x+camera_x))*180/math.pi*-1
        self.sprite = pygame.transform.rotate(pygame.image.load("bullet.png"), self.angle)
        self.sprite.set_colorkey((255,255,255))
    def update(self):
        self.x += self.speed*math.sin(math.radians(self.angle+90))
        self.y += self.speed*math.cos(math.radians(self.angle+90))
        if self.x+camera_x > screen_width or self.y+camera_y > screen_height or self.x+camera_x < 0 or self.y+camera_y < 0:
             return "dead"
        else:
            screen.blit(self.sprite, (self.x+camera_x,self.y+camera_y))
            return "ok"
        
def display(camera_x, camera_y, tilelist):
    for tile in tilelist.keys():
        if tilelist[tile] in object_types:
            # Takes objects and makes classes out of them
            add_object(tile, tilelist[tile])
            del tilelist[tile]
        else:
            r = tileset[tilelist[tile]].get_rect()
            r.move_ip(((tile[0]*tile_size) + camera_x, (tile[1]*tile_size) + camera_y))
            screen.blit(tileset[tilelist[tile]], r)
    for ob in object_list:
        ob.draw()

def add_object(xy, type):
    object_list.append( object_base(xy[0], xy[1], type) )
bullets = []
flag = 0 # terrible, terrible hack. See below.

connection = sqlite.connect("../Map Editor/database.db") 
cursor = connection.cursor()
objects = cursor.execute("SELECT position, name FROM tiles")
tilelist = {}
for line in objects:
    if line[1].encode("UTF-8") in object_types: #load objects
        x,y = eval(line[0])
        object_list.append( object_base(x, y, line[1].encode("UTF-8")) )
    else:
        position = eval(line[0])
        tilelist[position] = line[1].encode("UTF-8")
cursor.close()
connection.close()

while True:
    pressed_keys = pygame.key.get_pressed()
    mouseX, mouseY = pygame.mouse.get_pos()
    c.tick(30)
    screen.fill((0, 0, 0))
    display(camera_x, camera_y, tilelist)
    Hero.update(pressed_keys)
    for event in pygame.event.get(): 
        if event.type == QUIT: 
            pygame.quit()
            sys.exit()
    if pressed_keys[K_ESCAPE]:
        pygame.quit()
        sys.exit()

    if pressed_keys[K_c] and flag != 1: # hack to make it only register once per press, so it can't be held down
        if camera_snap_to_hero == True:
            camera_snap_to_hero = False
        else: camera_snap_to_hero = True
        flag = 1
    if pressed_keys[K_c] != True and flag == 1: # yup. Hacky. Very much so. Can we replace with keyup? Need more documentation on hand. ;__;
        flag = 0
    if camera_snap_to_hero == True: # whoo hoo, camera snap!
        camera_x -= (Hero.x + camera_x) - screen_width/2
        camera_y -= (Hero.y + camera_y) - screen_height/2
    if pygame.mouse.get_pressed()[0] == 1:
        bullets.append(Bullet())

    for b in bullets:
        if b.update() == "dead": bullets.remove(b)

    pygame.display.update()
    if Hero in object_list:
        print "UH OH"
